package org.lionsteins.eddie.client;

import java.util.ArrayList;
import java.util.Date;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.maps.client.InfoWindow;
import com.google.gwt.maps.client.InfoWindowContent;
import com.google.gwt.maps.client.MapWidget;
import com.google.gwt.maps.client.Maps;
import com.google.gwt.maps.client.control.Control;
import com.google.gwt.maps.client.control.ControlAnchor;
import com.google.gwt.maps.client.control.ControlPosition;
import com.google.gwt.maps.client.control.LargeMapControl;
import com.google.gwt.maps.client.event.MarkerClickHandler;
import com.google.gwt.maps.client.geom.LatLng;
import com.google.gwt.maps.client.geom.Point;
import com.google.gwt.maps.client.geom.Size;
import com.google.gwt.maps.client.overlay.Icon;
import com.google.gwt.maps.client.overlay.Marker;
import com.google.gwt.maps.client.overlay.MarkerOptions;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CaptionPanel;
import com.google.gwt.user.client.ui.DockLayoutPanel;
import com.google.gwt.user.client.ui.FormPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootLayoutPanel;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.datepicker.client.DateBox;
import com.google.gwt.user.datepicker.client.DateBox.Format;



/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class Eddie2 implements EntryPoint {
	

	ArrayList<AlertBean> allAlerts = null;
	ScrollPanel sp = new ScrollPanel();
	ArrayList<String> content;
	ArrayList<Integer> cutoffs;
	int index = 0;
	DockLayoutPanel dock1 = new DockLayoutPanel(Unit.PX);
	private boolean needsLegend = true;
	Label explan = new Label();
	int ext;

	private Control ctrlOverall;
	private Control helpControl;
	private CaptionPanel widgetOverall;
	private String helpContent;
	private Image imageWidget;
	private MapWidget mapWidget;
	private LatLng latlonSanDiego;
	private ContentList myContentList;
	
	
	
	
	/**
	 * The message displayed to the user when the server cannot be reached or
	 * returns an error.
	 */
	private static final String SERVER_ERROR = "An error occurred while "
			+ "attempting to contact the server. Please check your network "
			+ "connection and try again.";

	/**
	 * Create a remote service proxy to talk to the server-side Greeting service.
	 */
	private final GreetingServiceAsync greetingService = GWT
			.create(GreetingService.class);

	/**
	 * This is the entry point method.
	 */
	public void onModuleLoad() {
		sp.add(dock1);
		/*
		 * Asynchronously loads the Maps API.
		 *
		 * The first parameter should be a valid Maps API Key to deploy this
		 * application on a public server, but a blank key will work for an
		 * application served from localhost.
		 */		
		
		Maps.loadMapsApi("", "2",false, new Runnable() {
			public void run() {	
				System.out.println("Map is loaded");
				buildUi();
				String query = Window.Location.getQueryString();
				for(String q : query.split("&"))
				{
					if(q.contains("date="))
					{
						q = q.replace("?", "");
						q = q.replace("date=", "");

					}
				}				

			}
		});				

		dock1.setSize("20%", "100%");
		final FormPanel form = new FormPanel("_self");
		form.setMethod(FormPanel.METHOD_POST);	
		HTML center = new HTML("<center>");

		final Label startDateLabel = new Label();
		startDateLabel.setText("Start Date");
		Date today = new Date();
		Format myDateBoxFormat = new MyDateBoxFormat();
		final DateBox startDateTextBox = new DateBox( new MyDatePicker(), today, myDateBoxFormat);
		dock1.addNorth(center, 1);
		dock1.addNorth(startDateLabel, 20);
		dock1.addNorth(startDateTextBox, 30);
		final Label endDateLabel = new Label();
		endDateLabel.setText("End Date");


		final DateBox endDateTextBox = new DateBox( new MyDatePicker(), today, myDateBoxFormat);


		// Set the default value
		//datePicker2.setValue(new Date(), true);
		Button b = new Button("Submit");
		b.addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				// adding the prefix because that is how the back end expects it.
				getAlerts(new java.sql.Date(startDateTextBox.getValue().getTime()),
						new java.sql.Date(endDateTextBox.getValue().getTime()));
			}

		});
		b.setWidth("80px");
		b.removeStyleName("gwt-Button");
		b.addStyleName("MattButton");
		// Add the widgets to the page
		Label spacing = new HTML("<br /><br />");
		Label test = new HTML("<br />");
		explan.setText("\nSelect date range then click submit");
		dock1.addNorth(spacing, 20);
		dock1.addNorth(endDateLabel,20);
		dock1.addNorth(endDateTextBox,30);
		//dock1.addNorth(datePicker2,215);
		dock1.addNorth(b, 30);
		dock1.addNorth(test, 20);
		dock1.addNorth(explan, 50);
		int height = Window.getClientHeight();
		int blankspace = Math.max(0, height-770);
		dock1.addNorth(spacing, blankspace);
		dock1.addStyleName("dock");
		myContentList = new ContentList();
		dock1.addNorth(myContentList, 200);
		
		myContentList.setListner(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				
				int selected = myContentList.getSelectedIndex();
				AlertBean alertBean = allAlerts.get(selected);
				if (alertBean != null){
					LatLng position = null;
					position = LatLng.newInstance(alertBean.getLat(),alertBean.getLon());
					mapWidget.panTo(position);
				}
			}
			
		});

		RootLayoutPanel.get().add(dock1);		
	}
	
	
	


	private LatLng getSanDiegoLatLong() {
		if (latlonSanDiego == null){
			// 
			try {
				// was originally at 32.83049, -117.122717
				latlonSanDiego = LatLng.newInstance(32.941844,-117.387772);
			} catch (Exception e) {

			}
		}
		return latlonSanDiego;

	}

	/**
	 * although we are loading static content, the content is hung off the map which isn't shown until
	 * the first submit event.
	 */
	private void loadStaticContent() {
		


	}

	private void getAlerts(java.sql.Date startDate, java.sql.Date endDate){
		GreetingServiceAsync server= (GreetingServiceAsync)GWT.create(GreetingService.class);

		server.getAlerts(startDate, endDate, new AsyncCallback<ArrayList<AlertBean>>() {

			
			public void onFailure(Throwable caught) {
				// do some UI stuff to show failure
				caught.printStackTrace();
			}

			@Override
			public void onSuccess(ArrayList<AlertBean> result) {
				allAlerts = result;
				loadResults();
			}


		});
	}

	private void loadResults() {
		mapWidget.clearOverlays();

		if(allAlerts.size() == 0)
		{
			explan.setText("\nNo alerts were found in this date range");
		}
		else
		{
			explan.setText("\nClick on a circle on the map for detailed information about alerts in that area");
		}
		myContentList.clear();
		for(AlertBean ca : allAlerts)
		{			
			StringBuffer sb = new StringBuffer();
			if (ca.getDate() != null) {
				sb.append("Date: " + ca.getDate().toGMTString() + "<br/>");
				
			}
			sb.append(  ca.getId() +"> Foo" +  "</a></P>");
			// Open a map centered on San Diego
			myContentList.addItem( "sender: "+ ca.getSender() + " date: "+ ca.getDate());
			if (mapWidget != null){
				LatLng position = null;
				if (ca.getLat() != null && ca.getLon() != null ){
					position = LatLng.newInstance(ca.getLat(),ca.getLon());
				} else {
					position = getSanDiegoLatLong();
				}
				MarkerOptions mo = MarkerOptions.newInstance();			
				mo.setTitle(ca.getLocation());
				final Marker mark = new Marker(position,mo);  
				mapWidget.addOverlay(mark);
				StringBuffer sbContent = new StringBuffer();
				sbContent.append("<br> sender: ");
				sbContent.append(ca.getSender());
				sbContent.append(" <br> date:");
				sbContent.append(ca.getDate());
				sbContent.append(" <br> location:");
				sbContent.append(ca.getLocation());
				sbContent.append(" <br> type:");
				sbContent.append(ca.getIncidentType());
				sbContent.append("<br/>");
				final String content = sbContent.toString();

				mark.addMarkerClickHandler(new MarkerClickHandler() {
					public void onClick(MarkerClickEvent event) {
						InfoWindow info = mapWidget.getInfoWindow();
						HTML ChartHTML = new HTML(content);
						InfoWindowContent iwc = new InfoWindowContent(new HTML("<div class=window>" + ChartHTML + "</div>"));
						iwc.setMaxWidth(390);
						info.open(mark, iwc);
					}
				});
			}
		}

	}

	private void buildUi() {

		initMap();
		//final VerticalPanel panel = new VerticalPanel();

		DockLayoutPanel dock = new DockLayoutPanel(Unit.PCT);
		if (mapWidget != null){
			dock.addEast(mapWidget, 80);			
		}
		dock.addWest(dock1, 20);

		// Add the map to the HTML host page
		RootLayoutPanel.get().remove(dock1);
		RootLayoutPanel.get().add(dock);
	}

	private void initMap() {
		try {
			if (mapWidget == null){
				mapWidget = new MapWidget(getSanDiegoLatLong(),10);
			}

			mapWidget.clearOverlays();
			content = new ArrayList<String>();
			mapWidget.setSize("100%", "100%");
			// Add some controls for the zoom level
			mapWidget.addControl(new LargeMapControl());
		} catch (Exception e) {

		}
	}


	private void openChildWindow(String web) {
		openChildWindowJS(web);
	}

	/**
	 * interface to the JavaScript api
	 * @param url
	 */
	native void openChildWindowJS(String url)  /*-{
		window.open(url);
	}-*/;



	private ArrayList<Icon> createIconList() {
		ArrayList<Icon> icons = new ArrayList<Icon>();
		Icon icon = createIcon("b91c4caff22b475c863b0424391ba2ba-800.png");			
		Icon icon2 = createIcon("3b8832b062ff4342881ba30c4374da54-800.png");			
		Icon icon3 = createIcon("4703d39f0d7142cab29881784ddd5a97-800.png");			
		Icon icon4 = createIcon("2876f5fe8c044fc89747aeae59181768-800.png");	

		icons.add(icon);
		icons.add(icon2);
		icons.add(icon3);
		icons.add(icon4);
		return icons;
	}

	private Icon createIcon(String Url) {
		Icon icon = Icon.newInstance();		
		icon.setImageURL(Url);
		icon.setIconSize(Size.newInstance(30, 30));
		icon.setIconAnchor(Point.newInstance(6, 20));
		icon.setInfoWindowAnchor(Point.newInstance(14, 4));
		return icon;
	}

	private int whichIcon(Long long1)
	{
		if(long1 < cutoffs.get(0))
			return 0;
		if(long1 < cutoffs.get(1))
			return 1;
		if(long1 < cutoffs.get(2))
			return 2;
		return 3;	
	}


	
}
